<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		
		<script>
			
			// 获取原型
			const arrayProto = Array.prototype
			// 创建新原型对象
			const arrayMethods = Object.create(arrayProto);
			// 给新原型实现这些函数
			[
				'push',
				'pop',
				'shift',
				'unshift',
				'splice',
				'sort',
				'reverse'
			]
			.forEach(function(method) {
				// 获取新原型函数（此时未实现undefined）
				const original = arrayProto[method]
				// 给新原型添加函数实现
				Object.defineProperty(arrayMethods, method, {
					value: function mutator() {
						let i = arguments.length
						// 获取参数
						const args = new Array(i)
						while(i--) {
							args[i] = arguments[i]
						}
						// 实现函数
						const result = original.apply(this, args)
						// 是否更改数组本身
						let inserted
						switch(method) {
							case 'push':
								inserted = args
								console.log('新数组为：\n');
								console.log(this);
								console.log('数组末尾增加了' + inserted);
								break
							case 'unshift':
								inserted = args
								break
							case 'splice':
								inserted = args.slice(2)
								break
						}
						return result
					},
					enumerable: true,
					writable: true,
					configurable: true
				})
			})
			
			function Observer(value) {
				// 如果是数组就更改其原型指向
				if(Array.isArray(value)) {
					value.__proto__ = arrayMethods
					ObserverArray(value)
				}
			}
			
			// 观测数据元素
			function ObserverArray(items) {
				for(let i = 0, l = items.length; i < l; i++) {
					Observer(items[i])
				}
			}
			
			var arrValue = ['a', 'b'];
			
			Observer(arrValue);
			arrValue.push('c');
			
		</script>
		
	</body>
</html>
